/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.tabbedproperties.section;

import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.text.Assert;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.uml.State;

import com.cea.papyrus.core.commands.ChangeGraphNodePropertyCommand;
import com.cea.papyrus.core.editor.CommandStackUtils;
import com.cea.papyrus.core.tabbedproperties.PropertyViewSection;
import com.cea.papyrus.core.utils.LookForElement;
import com.cea.papyrus.diagram.statemachine.helper.NodeStateHelper;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.Property;

/**
 * Manages presentation section of States.
 *
 * @author David Servat
 * @since 11 apr. 07
 */
public class StatePresentationSection extends PropertyViewSection{

	/** The check box show deferrableTriggers. */
	private Button checkBoxShowDeferrableTriggers;

	/** The current deferrableTriggers appearance. */
	private boolean currentDeferrableTriggersAppearance;
	
	/** The show deferrableTriggers listener. */
	private SelectionListener showDeferrableTriggers;
	
	/** The check box show entry. */
	private Button checkBoxShowEntry;

	/** The current entry appearance. */
	private boolean currentEntryAppearance;
	
	/** The show entry listener. */
	private SelectionListener showEntry;
	
	/** The check box show exit. */
	private Button checkBoxShowExit;

	/** The current exit appearance. */
	private boolean currentExitAppearance;
	
	/** The show exit listener. */
	private SelectionListener showExit;
	
	/** The check box show doActivity. */
	private Button checkBoxShowDoActivity;
		
	/** The current doActivity appearance. */
	private boolean currentDoActivityAppearance;
	
	/** The show doActivity listener. */
	private SelectionListener showDoActivity;
	
	/**
	 * Creates the controls.
	 * 
	 * @param tabbedPropertySheetPage the tabbed property sheet page
	 * @param parent the parent
	 */
	public void createControls(final Composite parent, final TabbedPropertySheetPage tabbedPropertySheetPage){
		super.createControls(parent, tabbedPropertySheetPage);
		final Composite composite = this.getWidgetFactory().createFlatFormComposite(parent);
		FormData data;
		
		//show entry
		checkBoxShowEntry = this.getWidgetFactory().createButton(composite, "Show Entry", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(0, 100);
		data.top = new FormAttachment(0, 0);
		checkBoxShowEntry.setLayoutData(data);
		
		showEntry = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof State){
					if(diagramElement != null){
						Property property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_ENTRY);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		checkBoxShowEntry.addSelectionListener(showEntry);
		
		//show doActivity
		checkBoxShowDoActivity = this.getWidgetFactory().createButton(composite, "Show DoActivity", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowEntry, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowDoActivity.setLayoutData(data);
		
		showDoActivity = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof State){
					if(diagramElement != null){
						Property property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_DO_ACTIVITY);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		checkBoxShowDoActivity.addSelectionListener(showDoActivity);
		
		//show exit
		checkBoxShowExit = this.getWidgetFactory().createButton(composite, "Show Exit", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowDoActivity, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowExit.setLayoutData(data);
		
		showExit = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof State){
					if(diagramElement != null){
						Property property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_EXIT);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		checkBoxShowExit.addSelectionListener(showExit);
		
		//show deferrableTriggers
		checkBoxShowDeferrableTriggers = this.getWidgetFactory().createButton(composite, "Show DeferrableTriggers", SWT.CHECK);
		data = new FormData();
		data.left = new FormAttachment(checkBoxShowExit, 20);
		data.top = new FormAttachment(0, 0);
		checkBoxShowDeferrableTriggers.setLayoutData(data);
		
		showDeferrableTriggers = new SelectionListener(){
			/**
			 * Widget default selected.
			 * 
			 * @param e the e
			 */
			public void widgetDefaultSelected(SelectionEvent e){}

			/**
			 * Widget selected.
			 * 
			 * @param e the e
			 */
			public void widgetSelected(SelectionEvent e){
				if(umlElement instanceof State){
					if(diagramElement != null){
						Property property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_DEFERRABLE_TRIGGERS);
						if(property != null){
							ChangeGraphNodePropertyCommand command;
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_NOT_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							else{
								command = new ChangeGraphNodePropertyCommand(property, NodeStateHelper.STATE_DISPLAY){
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void redo(){
										super.redo();
										refresh();
									}
									/**
									 * Overriden to add refresh().
									 */
									@Override
									public void undo(){
										super.undo();
										refresh();
									}
								};
							}
							//execute command
							CommandStack stack = CommandStackUtils.getCommandStack();
							Assert.isNotNull(stack, "Impossible to adapt current editor into a CommandStack");
							stack.execute(command);
						}
					}		
				}
			}
		};
		checkBoxShowDeferrableTriggers.addSelectionListener(showDeferrableTriggers);
				
		//label of the section
		CLabel statePresentationLabel = this.getWidgetFactory().createCLabel(composite, "Display Options:");
		data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(checkBoxShowEntry, -ITabbedPropertyConstants.HSPACE);
		data.top = new FormAttachment(checkBoxShowEntry, 0, SWT.CENTER);
		statePresentationLabel.setLayoutData(data);
	}

	/**
	 * Refreshes the view.
	 */
	@Override
	public void refresh(){
		if(!checkBoxShowDeferrableTriggers.isDisposed() && !checkBoxShowDoActivity.isDisposed() && !checkBoxShowEntry.isDisposed() && !checkBoxShowExit.isDisposed()){
			//remove all listeners
			checkBoxShowDeferrableTriggers.removeSelectionListener(showDeferrableTriggers);
			checkBoxShowDoActivity.removeSelectionListener(showDoActivity);
			checkBoxShowEntry.removeSelectionListener(showEntry);
			checkBoxShowExit.removeSelectionListener(showExit);
			
			if((diagramElement != null) && (((GraphElement)diagramElement).getSemanticModel() != null)){
				if(umlElement instanceof State){
					Property property;
					
					if(((State)umlElement).getEntry() != null){
						checkBoxShowEntry.setEnabled(true);
						property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_ENTRY);
						if(property != null){
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								currentEntryAppearance = true;
							}
							else{
								currentEntryAppearance = false;
							}
						}
					}
					else{ 
						checkBoxShowEntry.setEnabled(false);
						currentEntryAppearance = false;
					}
					
					if(((State)umlElement).getDoActivity() != null){
						checkBoxShowDoActivity.setEnabled(true);
						property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_DO_ACTIVITY);
						if(property != null){
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								currentDoActivityAppearance = true;
							}
							else{
								currentDoActivityAppearance = false;
							}
						}
					}
					else{
						checkBoxShowDoActivity.setEnabled(false);
						currentDoActivityAppearance = false;
					}
					
					if(((State)umlElement).getExit() != null){
						checkBoxShowExit.setEnabled(true);
						property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_EXIT);
						if(property != null){
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								currentExitAppearance = true;
							}
							else{
								currentExitAppearance = false;
							}
						}
					}
					else{
						checkBoxShowExit.setEnabled(false);
						currentExitAppearance = false;
					}
						
					if(!((State)umlElement).getDeferrableTriggers().isEmpty()){
						checkBoxShowDeferrableTriggers.setEnabled(true);
						property = diagramElement.getProperty(NodeStateHelper.STATE_DISPLAY_DEFERRABLE_TRIGGERS);
						if(property != null){
							if(property.getValue().equals(NodeStateHelper.STATE_DISPLAY)){
								currentDeferrableTriggersAppearance = true;
							}
							else{
								currentDeferrableTriggersAppearance = false;
							}
						}
					}
					else{
						checkBoxShowDeferrableTriggers.setEnabled(false);
						currentDeferrableTriggersAppearance = false;
					}
						
				}				
			}
			else{
				checkBoxShowDeferrableTriggers.setEnabled(false);
				checkBoxShowDoActivity.setEnabled(false);
				checkBoxShowEntry.setEnabled(false);
				checkBoxShowExit.setEnabled(false);
			}
			checkBoxShowDeferrableTriggers.setSelection(currentDeferrableTriggersAppearance);
			checkBoxShowDoActivity.setSelection(currentDoActivityAppearance);
			checkBoxShowEntry.setSelection(currentEntryAppearance);
			checkBoxShowExit.setSelection(currentExitAppearance);
			
			checkBoxShowDeferrableTriggers.addSelectionListener(showDeferrableTriggers);
			checkBoxShowDoActivity.addSelectionListener(showDoActivity);
			checkBoxShowEntry.addSelectionListener(showEntry);
			checkBoxShowExit.addSelectionListener(showExit);
		}		
	}
	
	/**
	 * @see com.cea.papyrus.core.ui.properties.tabbed.PropertyViewSection#dispose()
	 */
	@Override
	public void dispose(){
		super.dispose();
		if((checkBoxShowDeferrableTriggers != null) && !checkBoxShowDeferrableTriggers.isDisposed())
			checkBoxShowDeferrableTriggers.removeSelectionListener(showDeferrableTriggers);
		if((checkBoxShowDoActivity != null) && !checkBoxShowDoActivity.isDisposed())
			checkBoxShowDoActivity.removeSelectionListener(showDoActivity);
		if((checkBoxShowEntry != null) && !checkBoxShowEntry.isDisposed())
			checkBoxShowEntry.removeSelectionListener(showEntry);
		if((checkBoxShowExit != null) && !checkBoxShowExit.isDisposed())
			checkBoxShowExit.removeSelectionListener(showExit);
	}
}